//========== 调试开关配置 ==========
const DEBUG_ENABLED = false; // 主开关：true=开启所有打印，false=关闭所有打印

// 条件打印函数
function debugLog(...args) {
    if (DEBUG_ENABLED) {
        console.log(...args);
    }
}

//========== 原有代码开始 ==========
//如果代理函数的时候，打印了函数的所有内容了，证明没有保护该函数
ffglobal = {};
//描述符检测，函数toString检测
!(() => {
    "use strict";
    const $toString = Function.toString; //hook Function.toString 且命名为myToString
    //变量名取随机数防检测
    const myFunction_toString_symbol = Symbol(
        "(".concat("", ")_", (Math.random() + "").toString(36))
    );
    const myToString = function () {
        return (
            (typeof this == "function" && this[myFunction_toString_symbol]) ||
            $toString.call(this)
        ); //谁调用这个方法,this就是谁,比如boda调用,这个this就是boda
    };

    function set_native(func, key, value) {
        //定义描述符
        Object.defineProperty(func, key, {
            enumerable: false,
            configurable: true,
            writable: true,
            value: value,
        });
    }
    delete Function.prototype["toString"]; //删除原型链上的toString
    set_native(Function.prototype, "toString", myToString); //自己定义个getter方法
    //myToString的 myFunction_toString_symbol属性设置为  function toString() { [native code] }
    //myFunction_toString_symbol= function toString() { [native code] }
    set_native(
        Function.prototype.toString,
        myFunction_toString_symbol,
        "function toString() { [native code] }"
    ); //套个娃 保护一下我们定义的toString 否则就暴露了
    ffglobal.safefunction = (func, name) => {
        set_native(
            func,
            myFunction_toString_symbol,
            `function ${(myFunction_toString_symbol, name || "")}() { [native code] }`
        );
        set_native(func, "name", `${(myFunction_toString_symbol, name || "")}`);
        // }
    }; //导出函数到globalThis
}).call(this);
//对象标识符检测
ffglobal.reNameObj = function reNameObj(obj, obname) {
    Object.defineProperty(obj.prototype, Symbol.toStringTag, {
        value: obname,
        configurable: true,
        writable: false,
        enumerable: false,
    });
};

/////============================
window = top = self = parent = globalThis;
process_ = process;
delete global;
delete __dirname;
delete __filename;
delete process;
delete module;
// delete require;
delete exports;
XMLHttpRequest = function XMLHttpRequest() {
    debugger;
};
ffglobal.safefunction(XMLHttpRequest, "XMLHttpRequest");
XMLHttpRequest.prototype.send = function send() {
    debugger;
};
ffglobal.safefunction(
    XMLHttpRequest.prototype.send,
    "XMLHttpRequest.prototype.send"
);
window.requestAnimationFrame = function requestAnimationFrame() {
    debugger;
};
ffglobal.safefunction(window.requestAnimationFrame, "requestAnimationFrame");
window._sdkGlueVersionMap = {
    sdkGlueVersion: "1.0.0.64-fix.01",
    bdmsVersion: "1.0.1.19-fix.01",
    captchaVersion: "4.0.10",
};
window.EventSource = function () { };
ffglobal.safefunction(window.EventSource, "EventSource");
window.addEventListener = function () { };
ffglobal.safefunction(window.addEventListener, "addEventListener");
window.CanvasRenderingContext2D = function () { };
ffglobal.safefunction(
    window.CanvasRenderingContext2D,
    "CanvasRenderingContext2D"
);
window.Audio = function () { };
ffglobal.safefunction(window.Audio, "Audio");
setTimeout = function setTimeout() { };
ffglobal.safefunction(setTimeout, "setTimeout");
setInterval = function setInterval() { };
ffglobal.safefunction(setInterval, "setInterval");
window.outerWidth = 1440;
window.outerHeight = 778;
window.innerWidth = 1440;
window.innerHeight = 778;
document = {};
HTMLAllCollection = function HTMLAllCollection() { };
ffglobal.safefunction(HTMLAllCollection, "HTMLAllCollection");
Object.defineProperty(HTMLAllCollection, Symbol.toStringTag, {
    value: "HTMLAllCollection",
});
_all = {
    [Symbol.toStringTag]: "HTMLAllCollection",
};
document.all = _all;
document.all.__proto__ = HTMLAllCollection.prototype;
ffglobal.safefunction(document.all, "_all");
debugLog("document.all.toString()==>", document.all.toString());
debugLog(
    "document.all[Symbol.toStringTag]==>",
    document.all[Symbol.toStringTag]
);

_documentElement = {
    [Symbol.toStringTag]: "HTMLHtmlElement",
};
document.documentElement = _documentElement;
ffglobal.safefunction(document.documentElement, "_documentElement");
debugLog(
    "document.documentElement.toString()==>",
    document.documentElement.toString()
);
debugLog(
    "document.documentElement[Symbol.toStringTag]==>",
    document.documentElement[Symbol.toStringTag]
);

DOMTokenList = function DOMTokenList() { };
ffglobal.safefunction(DOMTokenList, "DOMTokenList");
Object.defineProperties(DOMTokenList, {
    length: {
        value: 0,
        writable: false,
        enumerable: false,
        configurable: true,
    },
    name: {
        value: "DOMTokenList",
        writable: false,
        enumerable: false,
        configurable: true,
    },
});
Object.defineProperties(DOMTokenList.prototype, {
    entries: {
        value: function entries() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    keys: {
        value: function keys() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    values: {
        value: function values() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    forEach: {
        value: function forEach() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    add: {
        value: function add() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    contains: {
        value: function contains() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    item: {
        value: function item() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    remove: {
        value: function remove() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    replace: {
        value: function replace() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    supports: {
        value: function supports() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
    toggle: {
        value: function toggle() { },
        enumerable: true,
        configurable: true,
        writable: true,
    },
});
Object.defineProperty(DOMTokenList.prototype, Symbol.toStringTag, {
    value: "DOMTokenList",
});
_span = {
    classList: new DOMTokenList(),
    [Symbol.toStringTag]: "HTMLSpanElement",
};
ffglobal.safefunction(_span, "_span");

_canvas = {
    toDataURL: function toDataURL() {
        return "";
    },
};
ffglobal.safefunction(_canvas, "_canvas");
document.createElement = function createElement(arg) {
    debugLog("document中的createElement的参数为==>", arg);
    if (arg.toLowerCase() == "span") return _span;
    if (arg.toLowerCase() == "canvas") return _canvas;
    debugger;
};
ffglobal.safefunction(document.createElement, "createElement");

document.createEvent = function createEvent(arg) {
    debugLog("document中的createEvent的参数为==>", arg);
    debugger;
};
ffglobal.safefunction(document.createEvent, "createEvent");
document.addEventListener = function addEventListener(arg) {
    debugLog("document中的addEventListener的参数为==>", arg);
    debugger;
};
ffglobal.safefunction(document.addEventListener, "addEventListener");

location = {
    ancestorOrigins: {},
    href: "https://www.douyin.com/?recommend=1",
    origin: "https://www.douyin.com",
    protocol: "https:",
    host: "www.douyin.com",
    hostname: "www.douyin.com",
    port: "",
    pathname: "/",
    search: "?recommend=1",
    hash: "",
};
navigator = {
    appCodeName: "Mozilla",
    appName: "Netscape",
    appVersion:
        "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
    cookieEnabled: true,
    doNotTrack: null,
    hardwareConcurrency: 12,
    language: "zh-CN",
    languages: ["zh-CN", "zh"],
    maxTouchPoints: 0,
    onLine: true,
    pdfViewerEnabled: true,
    platform: "Win32",
    plugins: {
        length: 4,
        [Symbol.toStringTag]: "PluginArray",
        0: {
            name: "PDF Viewer",
            [Symbol.toStringTag]: "Plugin",
            length: 2,
        },
        1: {
            name: "ff_ss",
            [Symbol.toStringTag]: "Plugin",
            length: 2,
        },
        2: {
            name: "ss_ff",
            [Symbol.toStringTag]: "Plugin",
            length: 2,
        },
        3: {
            name: "FFloveSS",
            [Symbol.toStringTag]: "Plugin",
            length: 2,
        },
    },
    product: "Gecko",
    productSub: "20030107",
    userAgent:
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
    vendor: "Google Inc.",
    vendorSub: "",
    webdriver: false,
    storage: {
        [Symbol.toStringTag]: "StorageManager",
    },
    connection: {
        downlink: 10,
        downlinkMax: 10,
        effectiveType: "4g",
        rtt: 50,
        onchange: function () { },
        saveData: false,
    },
    userAgentData: {
        brands: [
            {
                brand: "Not)A;Brand",
                version: "8",
            },
            {
                brand: "Chromium",
                version: "138",
            },
            {
                brand: "Microsoft Edge",
                version: "138",
            },
        ],
        mobile: false,
        platform: "Windows",
    },
};

history = {};
screen = {
    availHeight: 901,
    availLeft: 0,
    availTop: 0,
    availWidth: 1412,
    colorDepth: 24,
    height: 1080,
    pixelDepth: 24,
    width: 1920,
};
localStorage = {
    xmst: "eCky5NPwTP8egExt-kFJgudpia2f7jFU_tSZCSXaRkh-z0lLonzYERc-0r5XyEBNpVTPfagUkavInLiq7TPsh7Ru7vJq26B6lHtu3U0F6eI85FubSVFlE_AfJX1SzxF1Wn0o0-AiEaBrrAV7WG9WTHYGlNkEVV59D97JZY45YASY5KEtQEHPqg==",
};
localStorage.getItem = function getItem(key) {
    debugLog("localStorage中的getItem的参数为==>", key);
    return localStorage[key];
};
ffglobal.safefunction(localStorage.getItem, "getItem");
sessionStorage = {};
sessionStorage.getItem = function getItem(key) {
    debugLog("sessionStorage中的getItem的参数为==>", key);
    return sessionStorage[key];
};
ffglobal.safefunction(sessionStorage.getItem, "getItem");

let count = 0;
let skipCount = 0; // 设置你想跳过的打印次数
// 你可以定义一个数组，用来存放你想要忽略的属性名
let ignoreList = [
    "document",
    "navigator",
    "location",
    "localStorage",
    "sessionStorage",
    "screen",
    "histroy",
];

function proxy(obj, objName) {
    let printedProps = new Set(); // 用 Set 来保存已经打印过的属性名,过滤掉重复属性
    let handler = {
        get(target, prop, receiver) {
            // 你可以检查 prop 是否在忽略列表中，如果是，就直接返回原始值，不进行拦截
            if (ignoreList.includes(prop)) {
                return Reflect.get(target, prop, receiver);
            }
            // 其他部分不变
            if (!printedProps.has(prop)) {
                let result = Reflect.get(target, prop, receiver);
                count++;
                if (typeof result === "function") {
                    if (result.toString().length <= 60) {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            debugLog(
                                "计数:",
                                count,
                                "[" + objName + "]",
                                "获取属性",
                                prop,
                                "   [FF函数经过]=>",
                                result.toString()
                            );
                        }
                    } else {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            debugLog(
                                "计数:",
                                count,
                                "[" + objName + "]",
                                "获取属性(===toString值太长===):",
                                prop
                            );
                        }
                    }
                    result = proxy(result, objName + "." + prop); // 对函数属性进行递归代理
                } else if (
                    typeof result === "object" &&
                    result !== null &&
                    result !== undefined
                ) {
                    if (result.toString().length <= 60) {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            debugLog(
                                "计数:",
                                count,
                                "[" + objName + "]",
                                "获取属性",
                                prop,
                                "   [OO对象经过]=>",
                                result.toString()
                            );
                        }
                    } else {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            debugLog(
                                "计数:",
                                count,
                                "[" + objName + "]",
                                "获取属性(===toString值太长===):",
                                prop
                            );
                        }
                    }
                    result = proxy(result, objName + "." + prop); // 对对象属性进行递归代理
                } else {
                    // 检查是否跳过打印
                    if (skipCount > 0) {
                        skipCount--;
                    } else {
                        debugLog(
                            "计数:",
                            count,
                            "[" + objName + "]",
                            "获取属性",
                            prop,
                            "   [值为]=>",
                            result
                        );
                    }
                }
                printedProps.add(prop); // 记录已经打印过的属性
                return result;
            }
            return Reflect.get(target, prop, receiver);
        },
        set(target, propKey, value, receiver) {
            // 同样，你可以检查 propKey 是否在忽略列表中，如果是，就直接返回原始值，不进行拦截
            if (ignoreList.includes(propKey)) {
                return Reflect.set(target, propKey, value, receiver);
            }
            // 其他部分不变
            if (!printedProps.has(propKey)) {
                count++;
                if (typeof value === "function") {
                    if (value.toString().length <= 60) {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            debugLog(
                                "计数:",
                                count,
                                "[" + objName + "]",
                                "  设置属性:",
                                propKey,
                                "   value:   ",
                                value.toString()
                            );
                        }
                    } else {
                        // 检查是否跳过打印
                        if (skipCount > 0) {
                            skipCount--;
                        } else {
                            debugLog(
                                "计数:",
                                count,
                                "[" + objName + "]",
                                "  设置属性(===toString值太长===):",
                                propKey
                            );
                        }
                    }
                } else {
                    // 检查是否跳过打印
                    if (skipCount > 0) {
                        skipCount--;
                    } else {
                        debugLog(
                            "计数:",
                            count,
                            "[" + objName + "]",
                            "  设置属性:",
                            propKey,
                            "   value:   ",
                            value
                        );
                    }
                }
                printedProps.add(propKey); // 记录已经打印过的属性
            }
            return Reflect.set(target, propKey, value, receiver);
        },
    };
    return new Proxy(obj, handler);
}

/////=========构造函数============
Window = function Window() { };
ffglobal.reNameObj(Window, "Window");

Document = function Document() { };
ffglobal.reNameObj(Document, "Document");
HTMLDocument = function HTMLDocument() { };
ffglobal.reNameObj(HTMLDocument, "HTMLDocument");
Location = function Location() { };
ffglobal.reNameObj(Location, "Location");
History = function History() { };
ffglobal.reNameObj(History, "History");
Navigator = function Navigator() { };

ffglobal.reNameObj(Navigator, "Navigator");
Screen = function Screen() { };
ffglobal.reNameObj(Screen, "Screen");
Storage = function Storage() { };
ffglobal.reNameObj(Storage, "Storage");
////================原型绑定================///////
window.__proto__ = Window.prototype;
document.__proto__ = HTMLDocument.prototype;
HTMLDocument.prototype.__proto__ = Document.prototype;
location.__proto__ = Location.prototype;
history.__proto__ = History.prototype;
navigator.__proto__ = Navigator.prototype;
screen.__proto__ = Screen.prototype;
localStorage.__proto__ = Storage.prototype;
sessionStorage.__proto__ = Storage.prototype;
/////===================代理对象=====================//////
window = proxy(window, "window");
document = proxy(document, "document");
navigator = proxy(navigator, "navigator");
location = proxy(location, "location");
history = proxy(history, "history");
screen = proxy(screen, "screen");
localStorage = proxy(localStorage, "localStorage");
sessionStorage = proxy(sessionStorage, "sessionStorage");
_canvas = proxy(_canvas, "_canvas");
all = proxy(document.all, "_all");
documentElement = proxy(document.documentElement, "_documentElement");
_span = proxy(_span, "_span");
/////==========代码==================
/* V 1.0.1.19-fix.01 */
require("./bdms.js");

function get_abgous(url) {
    var t = {
        aid: 6383,
        pageId: 6241,
        paths: [
            "^/webcast/",
            "^/aweme/v1/",
            "^/aweme/v2/",
            "/v1/message/send",
            "^/live/",
            "^/captcha/",
            "^/ecom/",
        ],
        boe: false,
        ddrt: 8.5,
        ic: 8.5,
    };
    window.bdms.init(t);
    xhr = new XMLHttpRequest();
    xhr.bdmsInvokeList = [
        {
            args: ["GET", url, true],
        },
        {
            args: ["Accept", "application/json, text/plain, */*"],
        },
        {
            args: [
                "uifid",
                "163eead721bc91ca6f3a3cb4766a73c0638fabced1012e02c28bcbf3169aca5cb1348391d76f63e2f9da4d719c4da32217a9b2949c98efebcf51e3c9c7e1d0966c784065b26bf6b319b04de558d7cb318383c29fa3a83356e1edcec69ee2d2b9c261a4ab36ad07403666f4f2b321382d22bc25bc620e23bcf48eaac8ccce297a7305d63b5b82ddf5a8eb9dc5afb305639b5d8324a5feb6a13e74d04fbdcf11b6",
            ],
        },
    ];
    xhr.invokeList = [
        {
            name: "addEventListener",
            args: ["load", null],
        },
        {
            name: "addEventListener",
            args: ["error", null],
        },
    ];
    xhr._vc_status = 1;
    xhr.send(null);
    process = process_;
    debugLog("window.a_bogus =>", window.a_bogus);
    return window.a_bogus;
}

get_abgous();
